import { clientConfig } from "../../../Game/Scripts/Config/Config";
import { Code, ShareDefine } from "../../../Game/Scripts/Config/ShareDefine";
import ControlManager from "../../../Game/Scripts/dataMgr/ControlManager";
import { HttpPack } from "../../../Game/Scripts/dataMgr/HttpPack";
import ClientManager from "../Managers/ClientManager";
import ComTool from "../Managers/ComTool";
import ConfirmManager from "../Managers/ConfirmManager";
import EventMgr from "../Managers/EventMgr";
import NativeManager from "../Managers/NativeManager";
import SysNotifyManager from "../Managers/SysNotifyManager";
import { HttpUtils } from "../Utils/HttpUtils";
import NetWork from "./NetWork";

const {ccclass, property} = cc._decorator;

@ccclass
export default class NetManager extends cc.Component {

    public static Instance: NetManager = null;
    sendHttpPackDict: {};
    packReceiveServerTypeDict: {};
    AccountServerUrl: string;
    OrderServerUrl: string;
    ResServerUrl: string;
    sendPack: any;
    onLoad() {
        if (NetManager.Instance !== null) {
            this.destroy();
            return;
        }
        NetManager.Instance = this;
    }


    Init(){
        console.log("===========NetManager init=============");

        //输出发送封包字典
		// {
		//     0xFF00:packName
		// }
        this.sendHttpPackDict = {};

        //封包发送到那个服务器
		// {
		//     0xFF00:account,
		// }
        this.packReceiveServerTypeDict = {};

        let ClientHttpPackDict = HttpPack.ClientHttpPackDict;
        for (let packHeadName in ClientHttpPackDict) {
			let headNameList = packHeadName.split(".");
			if (headNameList.length != 3) {
				console.error("InitHttpPack ClientHttpPackDict packHeadName:%s error", packHeadName);
				continue
			}
			let headInt = Math.floor(parseInt(headNameList[1]));

			if (this.sendHttpPackDict.hasOwnProperty(headInt)) {
				console.error("InitHttpPack sendHttpPackDict have find(%s) headInt", packHeadName);
				continue
			}
			this.sendHttpPackDict[headInt] = ClientHttpPackDict[packHeadName];

			this.packReceiveServerTypeDict[headInt] = headNameList[2];
		}


        this.InitServerAddress();
    }

    	//初始化连接的服务器地址
	InitServerAddress() {
		this.AccountServerUrl = ['http://', clientConfig.AccountServerIP, ":", clientConfig.AccountServerPort, "/ClientPack"].join("");
		//this.AccountServerUrlHttps = ['https://', clientConfig["AccountServerIP"], ":", clientConfig["AccountServerPort"].toString()+'0', "/ClientPack"].join("");
		this.OrderServerUrl = ['http://', clientConfig.OrderServerIP, ":", clientConfig.OrderServerPort, "/ClientPack"].join("");
		this.ResServerUrl = ['http://', clientConfig.ResServerIP, ":", clientConfig.ResServerPort, "/ClientPack"].join("");

		// let gateServerInfo = app["GateServerInfo"];

		// console.warn("GateServer(%s:%s)", gateServerInfo["GateServerIP"], gateServerInfo["GateServerPort"], "b-g");
		// console.warn("AccountServer(%s)", this.AccountServerUrl, "b-g");
		// console.warn("OrderServer(%s)", this.OrderServerUrl, "b-g");
		// console.warn("ResServerUrl(%s)", this.ResServerUrl, "b-g");
		// console.warn("Server(%s:%s)", clientConfig["GameServerIP"], clientConfig["GameServerPort"], "b-g");
	}


	//初始化连接
	InitConnectServer () {
		// app.Client.OnEvent("ModalLayer", "OpenNet");

		// let clientConfig = app.Client.GetClientConfig();
		console.log('连接服务器地址配置:', clientConfig)

		let gameServerIP = clientConfig.GameServerIP;
		let gameServerPort = clientConfig["GameServerPort"];
		console.log("大厅开始连接服务器");
		//初始化连接服务器
		NetWork.Instance.InitWebSocket(gameServerIP, gameServerPort, this.OnWebSocketEvent.bind(this), this.OnConnectSuccess.bind(this));
	}

    	/**
	 * 获取url字符串格式
	 * @param dataDict
	 * @returns {String}
	 */
	GetUrlStr (dataDict:any) {

		if (!dataDict) {
			return ""
		}
		var urlSendStr = '?';
		for (var key in dataDict) {
			urlSendStr += key + '=' + dataDict[key] + '&';
		}
		//去掉最后一个&
		urlSendStr = urlSendStr.substring(0, urlSendStr.length - 1);

		return urlSendStr;
	}

	//获取http请求发送的封包
	GetHttpSendPack(head:number) {
		if (!this.sendHttpPackDict.hasOwnProperty(head)) {
			console.error("GetHttpSendPack sendHttpPackDict not find:%s", head);
			return
		}
		return { "Head": head }
	}

    
	//获取http封包发送的目的地地址
	GetHttpSendPackUrl (head) {
		let serverType = this.packReceiveServerTypeDict[head];
		if (!serverType) {
			console.log("GetHttpSendPackUrl(%s) not find", head);
			return
		}

		let url = "";
		switch (serverType) {
			case "account":
				url = this.AccountServerUrl;
				break
			case "order":
				url = this.OrderServerUrl;
				break
			case "res":
				url = this.ResServerUrl;
				break
			default:
				console.error("GetHttpSendPackUrl serverType:%s error", serverType);
				break
		}

		return url
	}

    	//发送HTTP请求
	SendHttpPack (sendPack:any,callback) {
		//console.log("sendPack Head:"+sendPack.Head);
		let serverUrl = this.GetHttpSendPackUrl(sendPack.Head);
		if (!serverUrl) {
			console.error("SendHttpPack(%s) not find serverUrl", sendPack);
			return
		}
		//开启模态层
		// app.Client.OnEvent("ModalLayer", "OpenNet");
		let argDict = { "Sign": "ddcat" };
		let argString = this.GetUrlStr(argDict);

		if (ShareDefine.IsDevelopment == 0) {
			console.log("[SendHttp](%s):", serverUrl, sendPack, "b-g");
		}
		this.sendPack = sendPack;
		console.log("============NetManager SendHttpPack===============",serverUrl);
		// this.httpRequest.SendHttpRequest(serverUrl, argString, "POST", sendPack);

        let strPack = JSON.stringify(sendPack);
        HttpUtils.PostJson(serverUrl,argString,strPack,(msgName,data)=>{
            // console.log("============NetManager SendHttpPack Res===============",data);
            callback && callback(data);
        })
	}

	//向服务器发起请求
	SendPack(eventName, sendPack, callback = (data) => {
		console.log("服务端返回成功",data)
	}, errorCallback = (data) => {
		console.log("服务端返回失败", data)
	}) {
		if (ControlManager.Instance.IsOpenVpn()) {
			return;
		}
		if (eventName != "heartBeat.CHeartBeatHandler") {
			console.error("向服务器发起请求"+eventName);
			console.log("向服务器发起请求", eventName, sendPack, callback, errorCallback);
		}
		//开启模态层
		EventMgr.Instance.Emit("ModalLayer", "OpenNet");
		NetWork.Instance.Request(eventName, sendPack, callback, errorCallback);
	}
	//向服务器发起请求,不触发网络
	SendPackOnly(eventName, sendPack, callback = null, errorCallback = null) {
		NetWork.Instance.Request(eventName, sendPack, callback, errorCallback);
	}
	//通知服务器得封包数据
	NotifyPack(eventName, sendPack) {
		NetWork.Instance.Notify(eventName, sendPack);
	}

	//注册封包事件(需要字符串封包头,才可以避免RegHttpNetPack相同封包头注册事件区分)
	RegNetPack(head, func, target) {
		head = head.toLocaleLowerCase();
		let valueType = Object.prototype.toString.call(head).slice("[object ".length, -1);
		if (valueType != "String") {
			console.error("RegNetPack need String head");
			return
		}

		if (!func || !target) {
			console.error("RegNetPack head:%s error", head);
			return
		}
		EventMgr.Instance.AddEventListener(head,func,target);
	}

	//取消封包注册
	UnRegNetPack(eventName, func,target) {
		EventMgr.Instance.RemoveEventListener(eventName,func,target);
	}

	//取消所有封包注册
	UnRegAllNetPack() {
		// this.emitter.removeAllListeners();
	}

	//服务器连接成功
	OnConnectSuccess(isReconnecting) {
		console.log("========服务器连接成功(大厅)==========");
		//关闭模态层
		// app.Client.OnEvent("ModalLayer", "ReceiveNet");
		// app.Client.OnEvent("ConnectSuccess", { "ServerName": "GameServer", "IsReconnecting": isReconnecting });
	
		EventMgr.Instance.Emit("ModalLayer", "ReceiveNet");
		EventMgr.Instance.Emit("ConnectSuccess", { "ServerName": "GameServer", "IsReconnecting": isReconnecting });
	}

	//websocket事件回掉
	OnWebSocketEvent(eventName, arg) {
		// console.log("大厅 OnWebSocketEvent 回调");
		//关闭模态层
		EventMgr.Instance.Emit("ModalLayer", "ReceiveNet");

		switch (eventName) {
			case "OnError":
				console.warn("连接超时");
				EventMgr.Instance.Emit("ConnectFail", { "ServerName": "GameServer", "EventType": "OnError" });
				break

			case "Reconnectd":
				console.warn("重连失败");
				EventMgr.Instance.Emit("ModalLayer", "StartReConnect");
				NetWork.Instance.ReConnect();
				break

			case "OnClose":
				console.warn("断开连接");
				EventMgr.Instance.Emit("ConnectFail", {
					"bCloseByLogout": arg[0],
					"ServerName": "GameServer",
					"EventType": "OnClose"
				});
				break

			case "OnKick":
				console.error("被T(%s)", arg["reason"]);
				SysNotifyManager.Instance.ShowSysMsg("Kick_ByServer");
				break

			case "OnReceive":
				this.OnReceive(arg[0], arg[1]);
				break

			case "OnCodeError":
				this.OnCodeError(arg[0], arg[1], arg[2]);
				break

			case "OnGMReceive":
				this.OnGMReceive(arg[0], arg[1]);
				break

			default:
				console.error("OnWebSocketEvent(%s):", eventName, arg);
				break
		}
	}

	OnConFirm(clickType, msgID, backArgList) {
		if (clickType != "Sure") {
			return
		}
		if ("goBuyCard" == msgID) {
			let clientConfig = ClientManager.Instance.GetClientConfig();
			if (app.PackDefine.APPLE_CHECK == clientConfig["appPackType"]) return
			app.FormManager().ShowForm(PreCfg.UIStore);
			app.FormManager().CloseForm("UIJoin");
			app.FormManager().CloseForm("UIChouJiang");
			return;
		} else if ("MSG_OPEN_GPS" == msgID) {
			if (cc.sys.isNative) {
				NativeManager.Instance.CallToNative("gpsSetting", []);
			}
			return;
		}
	}

	//封包事件回掉
	OnReceive(routeName, receivePack) {
		if (routeName != "splayerheartbeat" && routeName != "heartbeat.cheartbeathandler") {
			console.warn("===封包事件回掉==="+routeName);
			console.log("===封包事件回掉===", routeName, receivePack);

		}
		try {
			// this.emitter.emit(routeName, receivePack);
			EventMgr.Instance.Emit(routeName, receivePack);
		}
		catch (error) {
			console.error("OnReceive:%s", error.stack);
			console.error("OnReceive routeName :%s, receivePack:%s", routeName, JSON.stringify(receivePack));
		}
	}

	//封包事件失败回掉
	OnCodeError(eventName, code, resultInfo) {
		console.log("OnCodeError(%s) (%s) (%s):", eventName, code, JSON.stringify(resultInfo));

		let codeMsg = ["Code", code].join("_");
		//如果是错误提示类型,根据提示码提示,直接提示
		if (code ==  Code.ErrorSysMsg) {
			SysNotifyManager.Instance.ShowSysMsg(resultInfo["Msg"]);
		}
		// else if(code ==  Code.NotAllow){
		// 	SysNotifyManager.Instance.ShowSysMsg('MSG_SERVICE_NOTALLOW');
		// }
		else if (code == 5024) {
			SysNotifyManager.Instance.ShowSysMsg(resultInfo["Msg"]);
		}
		else if (code == 914) {
			SysNotifyManager.Instance.ShowSysMsg("您未满18周岁不允许游戏", [], 3);
		}
		else if (code == 105) {
			SysNotifyManager.Instance.ShowSysMsg("城市未开放");
		}
		else if (code == 914) {
			SysNotifyManager.Instance.ShowSysMsg('NotEnough_IdCardAgeValid');
		}

		//else if (code == 915) {
		//SysNotifyManager.Instance.ShowSysMsg('NotEnough_IdCardAgeNoValid');
		//app.FormManager().ShowForm("UIShiMing");
		//}

		else if (code == 304) {
			SysNotifyManager.Instance.ShowSysMsg("房间已经开始了");
		}
		else if (code == 12) {
			SysNotifyManager.Instance.ShowSysMsg(resultInfo["Msg"]);
		}
		else if (code == 5118) {
			SysNotifyManager.Instance.ShowSysMsg("错误验证码");
		}
		else if (code == 5116) {
			SysNotifyManager.Instance.ShowSysMsg("错误手机号");
		}
		else if (code == 5119) {
			app.Client.OnEvent("DoLogin", {});
		}
		else if (code == 6051) {
			SysNotifyManager.Instance.ShowSysMsg("修改后新上级推广员系数比例低于当前玩家比例，无法修改，请先修改玩家或新上级推广员的比例，使新上级推广员系数大于玩家系数");
		}
		else if (code == 916) {
			SysNotifyManager.Instance.ShowSysMsg("尊敬的各位用户:自12月6日00:00起，本游戏关服1天。预计12月7日00:00后恢复，以游戏内实际开服时间为准。");
		}
		else if (code == Code.InOtherRoomPlay) {
			SysNotifyManager.Instance.ShowSysMsg('MSG_IN_OTHER_ROOM_PLAY');
		}
		else if (code == 11) {
			SysNotifyManager.Instance.ShowSysMsg('网络连接失败，请联系客服');
		}
		else if (code == 6006) {
			//resultInfo
			SysNotifyManager.Instance.ShowSysMsg(resultInfo["Msg"]);
		} else if (code == 6017) {
			SysNotifyManager.Instance.ShowSysMsg('您被禁止该亲友圈游戏');
		}

		else if (code == 6052) {
			SysNotifyManager.Instance.ShowSysMsg('当前有人正在修改归属，请稍后再试');
		}

		else if (code == Code.CLUB_NOT_CREATE) {
			SysNotifyManager.Instance.ShowSysMsg('不是亲友圈创造者');
		}
		else if (code ==  Code.CLUB_NOT_PROMOTION) {
			SysNotifyManager.Instance.ShowSysMsg('不是推广员');
		}
		else if (code ==  Code.CLUB_NOT_EXIST_MEMBER_INFO) {
			SysNotifyManager.Instance.ShowSysMsg('亲友圈不存在成员信息');
		}
		else if (code ==  Code.CLUB_MEMBER_PROMOTION_BELONG) {
			SysNotifyManager.Instance.ShowSysMsg('修改归属的时候不能切换到原来的归属或者下线');
		}
		else if (code ==  Code.CLUB_MEMBER_PROMOTION_LEVEL_SHARE_LOWER) {
			SysNotifyManager.Instance.ShowSysMsg('当前分支下的下级推广员系数存在百分比形式，无法设置系数为固定值，请先修改');
		}
		else if (code ==  Code.CLUB_MEMBER_PROMOTION_LEVEL_SHARE_UP) {
			SysNotifyManager.Instance.ShowSysMsg('上级推广员系数为固定值，无法设置为百分比');
		}

		else if (code ==  Code.Maintain) {
			let finishttime = resultInfo["Msg"];
			SysNotifyManager.Instance.ShowSysMsg('服务器维护中,预计结束时间：' + ComTool.Instance.GetDateYearMonthDayHourMinuteString(finishttime));
		}
		else if (code ==  Code.ErrorNotRoomCard) {//房卡不足
			let desc = SysNotifyManager.Instance.GetSysMsgContentByMsgID("MSG_NotRoomCard");
			ConfirmManager.Instance.SetWaitForConfirmForm(this.OnConFirm.bind(this), "goBuyCard", []);
			app.FormManager().ShowForm("UIMessage", null,  Code.ConfirmBuyGoTo, 0, 0, desc)
		}
		else if (code == 911) {//房卡不足
			let cityId = resultInfo["Msg"];
			let selectCityConfig = app.SysDataManager().GetTableDict("selectCity");
			let cityName = selectCityConfig[cityId]["Name"];
			SysNotifyManager.Instance.ShowSysMsg('圈主或者主办方[' + cityName + "]钻石不足");
			//   	let desc = "当前["+cityName+"]钻石不足，请前往购买";
			// ConfirmManager.Instance.SetWaitForConfirmForm(this.OnConFirm.bind(this), "goBuyCard", []);
			//   	app.FormManager().ShowForm("UIMessage", null,  Code.ConfirmBuyGoTo, 0, 0,desc)
		}
		else if (code ==  Code.ErrorMaxRoom) {
			SysNotifyManager.Instance.ShowSysMsg('可以创建的房间数量不足');
		}

		else if (code ==  Code.NoPower_RoomJoinner) {
			SysNotifyManager.Instance.ShowSysMsg('您当前处于退出申请中，不能加入该游戏');
		}

		else if (code ==  Code.CLUB_PLAYER_EXIT_IN_OTHER_UNION) {
			SysNotifyManager.Instance.ShowSysMsg('已邀请或未找到该玩家或同赛事不同亲友圈不能重复拉人或距离退出该亲友圈不到10分钟或该玩家处于赛事黑名单，无法加入亲友圈');
		}


		else if (code ==  Code.EXIST_SAME_IP) {
			//SysNotifyManager.Instance.ShowSysMsg('MSG_SERVICE_NOTALLOW');
			SysNotifyManager.Instance.ShowSysMsg('拥有相同IP');
		} else if (code ==  Code.POSITIONING_NOT_ON) {
			app.FormManager().ShowForm("UIMessageGps");
		} else if (code ==  Code.APART_LOCATION) {
			SysNotifyManager.Instance.ShowSysMsg('您和房间内的玩家距离过近，禁止进入本房间');
		}

		else if (code ==  Code.ErrorNotQuanCard) {//圈币不足
			SysNotifyManager.Instance.ShowSysMsg('圈卡不足，请前往亲友圈商城购买圈卡');
			app.ClubManager().GetClubFormComponent().OnClick('btn_addRoomCard', null);
		}
		//如果有配置系统提示码,则提示错误提示码对应的文本
		else if (this.NewSysMsg.hasOwnProperty(codeMsg)) {

			let errorMsg = resultInfo["Msg"];
			//开发模式有 提示文本的话 显示错误文本
			if ( Code.IsDevelopment && errorMsg) {
				SysNotifyManager.Instance.ShowSysMsg("CodeErrorMsg", [errorMsg]);
			}
			//如果不是开发模式,弹通用的系统提示
			else {
				SysNotifyManager.Instance.ShowSysMsg(codeMsg);
			}
		}
		//如果配置表没有配置的错误码
		else {
			//如果是不需要提示的,不配置也不需要显示的系统提示码
			if ( Code.NoShowSysMsgCodeList.InArray(code)) {

			}
			//没有配置,是开发模式弹框
			else if ( Code.IsDevelopment) {
				SysNotifyManager.Instance.ShowSysMsg("CodeErrorMsg", [resultInfo["Msg"]]);
			}
		}
		EventMgr.Instance.Emit("CodeError", { "Code": code, "EventName": eventName, "Result": resultInfo });
	}

	//接受到GM命令汇报
	OnGMReceive(eventName, argDict) {
		EventMgr.Instance.Emit("ReceiveGM", argDict);
	}

	//------------操作函数-----------------------------

	//下线
	Disconnect(byLogout = false) {
		NetWork.Instance.Disconnect(byLogout);
	}

	SendGMPack (cmdString) {
		let sendPack = { "cmdString": cmdString };
		this.SendPack("game.C1105GMPack", sendPack)
	}

	OnPack_GMPack (serverPack) {
		EventMgr.Instance.Emit("GMPack", serverPack);
	}
}
